//
//  LLRefreshComponent.m
//  AnimateTest
//
//  Created by dl on 15/12/10.
//  Copyright © 2015年 dl. All rights reserved.
//

#import "LLRefreshComponent.h"
#import "LLRefreshConst.h"

@interface LLRefreshComponent ()
@property(strong, nonatomic) UIPanGestureRecognizer *pan;
@end

@implementation LLRefreshComponent

#pragma mark - 初始化

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // 准备工作
        [self prepare];

        // 默认是普通状态
        self.state = LLRefreshStateIdle;
    }
    return self;
}

- (void)prepare {
    // 基本属性
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    self.backgroundColor = [UIColor clearColor];
}

- (void)layoutSubviews {
    [super layoutSubviews];

    [self placeSubviews];
}

- (void)placeSubviews {
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];

    // 如果不是UIScrollView，不做任何事情
    if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return;

    // 旧的父控件移除监听
    [self removeObservers];

    if (newSuperview) { // 新的父控件
        // 设置宽度
        self.ll_width = newSuperview.ll_width;
        // 设置位置
        self.ll_left = 0;

        // 记录UIScrollView
        _scrollView = (UIScrollView *) newSuperview;
        // 设置永远支持垂直弹簧效果
        _scrollView.alwaysBounceVertical = YES;
        // 记录UIScrollView最开始的contentInset
        _scrollViewOriginalInset = _scrollView.contentInset;

        // 添加监听
        [self addObservers];
    }
}

#pragma mark - KVO监听

- (void)addObservers {
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [self.scrollView addObserver:self forKeyPath:LLRefreshKeyPathContentOffset options:options context:nil];
    [self.scrollView addObserver:self forKeyPath:LLRefreshKeyPathContentSize options:options context:nil];
    self.pan = self.scrollView.panGestureRecognizer;
    [self.pan addObserver:self forKeyPath:LLRefreshKeyPathPanState options:options context:nil];
}

- (void)removeObservers {
    [self.superview removeObserver:self forKeyPath:LLRefreshKeyPathContentOffset];
    [self.superview removeObserver:self forKeyPath:LLRefreshKeyPathContentSize];;
    [self.pan removeObserver:self forKeyPath:LLRefreshKeyPathPanState];
    self.pan = nil;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    // 遇到这些情况就直接返回
    if (!self.userInteractionEnabled) return;

    // 这个就算看不见也需要处理
    if ([keyPath isEqualToString:LLRefreshKeyPathContentSize]) {
        [self scrollViewContentSizeDidChange:change];
    }

    // 看不见
    if (self.hidden) return;
    if ([keyPath isEqualToString:LLRefreshKeyPathContentOffset]) {
        [self scrollViewContentOffsetDidChange:change];
    } else if ([keyPath isEqualToString:LLRefreshKeyPathPanState]) {
        [self scrollViewPanStateDidChange:change];
    }
}

- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change {
}

- (void)scrollViewContentSizeDidChange:(NSDictionary *)change {
}

- (void)scrollViewPanStateDidChange:(NSDictionary *)change {
}

#pragma mark 进入刷新状态

- (void)beginRefreshing {
    [UIView animateWithDuration:LLRefreshFastAnimationDuration animations:^{
        self.alpha = 1.0;
    }];
    self.pullingPercent = 1.0;
    // 只要正在刷新，就完全显示
    if (self.window) {
        self.state = LLRefreshStateRefreshing;
    } else {
        self.state = LLRefreshStateWillRefresh;
        // 刷新(预防从另一个控制器回到这个控制器的情况，回来要重新刷新一下)
        [self setNeedsDisplay];
    }
}

#pragma mark 结束刷新状态

- (void)endRefreshing {
    self.state = LLRefreshStateIdle;
}

#pragma mark 是否正在刷新

- (BOOL)isRefreshing {
    return self.state == LLRefreshStateRefreshing || self.state == LLRefreshStateWillRefresh;
}

#pragma mark 自动切换透明度

- (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha {
    _automaticallyChangeAlpha = automaticallyChangeAlpha;

    if (self.isRefreshing) return;

    if (automaticallyChangeAlpha) {
        self.alpha = self.pullingPercent;
    } else {
        self.alpha = 1.0;
    }
}

#pragma mark 根据拖拽进度设置透明度

- (void)setPullingPercent:(CGFloat)pullingPercent {
    _pullingPercent = pullingPercent;

    if (self.isRefreshing) return;

    if (self.isAutomaticallyChangeAlpha) {
        self.alpha = pullingPercent;
    }
}

#pragma mark - 内部方法

- (void)executeRefreshingCallback {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (self.refreshingBlock) {
            self.refreshingBlock();
        }
    });
}

@end
